package com.sghd.football.utils.encrypt;

import com.fasterxml.jackson.core.type.TypeReference;
import com.sghd.common.utils.json.JsonUtils;
import org.apache.commons.collections.MapUtils;

import java.security.SignatureException;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

/**
 * 解密工具类
 * 
 * @author AllenWu
 */
public class DecryptUtil {
	/**
	 * @param param
	 * @return
	 */
	public static boolean checkSign(Map<String, Object> param) {
		try {
			param.remove("playerID");
			String sign = (String)param.get("sign");
			param.remove("sign");
			StringBuffer sbuffer = new StringBuffer();
			Iterator<Entry<String, Object>> iter = param.entrySet().iterator();
			while (iter.hasNext()) {
				Entry<String, Object> entry = iter.next();
				sbuffer.append(entry.getValue());
			}
			return RSA.checkSign(sbuffer.toString().getBytes(), Base64.decode2(sign), Base64.decode2(Config.DE_PUBLICKEY));
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	/**
	 * 签名验证
	 * 
	 * @param data
	 *            需验证的数据
	 * @param publicKey
	 *            公钥
	 * @return JSONObject
	 * @throws Exception
	 */
	public static Map<String, Object> checkSign(String data, String publicKey) throws Exception {
		Map<String, Object> json = JsonUtils.string2GenericObject(data, new TypeReference<Map<String, Object>>() {
		});
		StringBuffer sbuffer = new StringBuffer();

		String sign = MapUtils.getString(json, "sign");
		json.remove("sign");

		Iterator<Entry<String, Object>> iter = json.entrySet().iterator();
		while (iter.hasNext()) {
			Entry<String, Object> entry = iter.next();
			sbuffer.append(entry.getValue());
		}
		boolean isPass = RSA.checkSign(sbuffer.toString().getBytes(), Base64.decode2(sign), Base64.decode2(publicKey));
		if (isPass)
			return json;
		else
			throw new SignatureException("签名验证失败！");
	}

	/**
	 * 签名验证
	 * 
	 * @param data
	 *            需验证的数据
	 * @param publicKey
	 *            公钥
	 * @param ENCODING
	 *            编码
	 * @return
	 * @throws Exception
	 */
	public static Map<String, Object> checkSign(String data, String publicKey, String ENCODING) throws Exception {
		Map<String, Object> json = JsonUtils.string2GenericObject(data, new TypeReference<Map<String, Object>>() {
		});
		StringBuffer sbuffer = new StringBuffer();
		String sign = (String)json.get("sign");
		json.remove("sign");

		Iterator<Entry<String, Object>> iter = json.entrySet().iterator();
		while (iter.hasNext()) {
			Entry<String, Object> entry = iter.next();
			sbuffer.append(entry.getValue());
		}
		boolean isPass = RSA.checkSign(sbuffer.toString().getBytes(ENCODING), Base64.decode2(sign), Base64.decode2(publicKey));
		//System.out.println(isPass);
		if (isPass)
			return json;
		else
			return null;
	}

	/**
	 * RSA解密
	 * 
	 * @param cryptograph
	 *            需要解密的数据
	 * @param privateKey
	 *            私钥
	 * @return
	 * @throws Exception
	 */
	public static String decryptRSA(String cryptograph, String privateKey) throws Exception {
		byte[] data = RSA.decrypt(Base64.decodeBase64(cryptograph.getBytes()), privateKey.getBytes(), Config.TRANSFORMATION_RSA);
		return new String(data);
	}

	/**
	 * 
	 * @param cryptograph
	 *            需要解密的数据
	 * @param privateKey
	 *            私钥
	 * @param ENCODING
	 *            编码
	 * @return
	 * @throws Exception
	 */
	public static String decryptRSA(String cryptograph, String privateKey, String ENCODING) throws Exception {
		byte[] data = RSA.decrypt(Base64.decodeBase64(cryptograph.getBytes()), privateKey.getBytes(), Config.TRANSFORMATION_RSA);
		return new String(data, ENCODING);
	}

	/**
	 * AES解密
	 * 
	 * @param cryptograph
	 *            需要解密的数据
	 * @param key
	 *            随机加密密钥
	 * @param iv
	 *            偏移密码
	 * @return
	 * @throws Exception
	 */
	public static String decryptAES(String cryptograph, String key, String iv) throws Exception {
		byte[] data;
		if (iv != null)
			data = AES.decrypt(Base64.decode(cryptograph.getBytes()), key.getBytes(), iv.getBytes());
		else
			data = AES.decrypt(Base64.decode(cryptograph.getBytes()), key.getBytes());
		return new String(data).trim();
	}

	/**
	 * AES解密
	 * 
	 * @param cryptograph
	 *            需要解密的数据
	 * @param key
	 *            随机加密密钥
	 * @param iv
	 *            偏移密码
	 * @param ENCODING
	 *            编码
	 * @return
	 * @throws Exception
	 */
	public static String decryptAES(String cryptograph, String key, String iv, String ENCODING) throws Exception {
		byte[] data;
		if (iv != null)
			data = AES.decrypt(Base64.decode(cryptograph.getBytes()), key.getBytes(), iv.getBytes());
		else
			data = AES.decrypt(Base64.decode(cryptograph.getBytes()), key.getBytes());
		return new String(data, ENCODING).trim();
	}

	public static Map<String, Object> getValidData(Map<String, Object> json) throws Exception {
		//System.out.println("<-----" + json.toString());
		// 需要解密
		if (MapUtils.getIntValue(json,"encrptType") == 1 || MapUtils.getIntValue(json,"encrptType") == 3) {
			String encryptData = MapUtils.getString(json, "encryptData");
			String encryptKey = MapUtils.getString(json, "encryptKey");
			String encryptIv = MapUtils.getString(json, "encryptIv");
			String AESKey = decryptRSA(encryptKey, Config.DE_PRIVATEKEY);
			String AESIv = "";

			if (isNotNullAndTrim(encryptIv))
				AESIv = decryptRSA(encryptIv, Config.DE_PRIVATEKEY);
			else
				AESIv = null;

			String data = decryptAES(encryptData, AESKey, AESIv);
			return DecryptUtil.checkSign(data, Config.DE_PUBLICKEY);
		} else
			return json;
	}
	
	public static void main(String[] args) throws Exception {
		String encryptData = "QlXUioH8yS5FqrtiptOMKPXA+0Dm2ByO7JzCMkixOGpCTLZWhQaSP8CKuMU9K0pccpJmkSiPQVVEFcM52cIgl6ikogUfn9sjaigppj4G4R/lu9hyQwMpK5UxkzCLjA4+E0aPGLFAEBYJdrrjV8BlkUfQaE5Czie4EIqShppM+2pg95uHWf+YbiALm18ZqBIo3IdC7wYoKGB+sas8qlC9tH9ZrQDKjG22RYekCuNaIsnQvhhrZGQVTnPcm7c6esg1gSq4+7PInswd+Rhn73TR4BysdIxodzVwPSsfXgaWM3YEYK6GujP8MfIY0QxYtDOmAIV6+x0FWiQwoIlMDJLMSjGpJtnn0jp6646h6vpccp99mrrLu9OrUUW9Lp2udB0xmotd36qDjYzDSZ/5HCU0yA==";
		//String encryptData = "uY/vEfnFwwySlf1OqFi/upnPcmtUsnGRFqnH/ZMKaNWuQuvGq7UDpNNd+/+rwyG6F8evUrgh0b1TLiuQ+92srArHucQaAJlzkovC0+OQizYyV5DeFOcFfEHl7AZtcpxhDmGZDt9ykUkOI3YA4U94Uz+lf3zuSKnLwmrMcgwWe/EFUsvtyd8Zpq4Pp1XjVKQp7g9hfn82MJ+fSCNui0Y51DTszkD2vv6stA6/EOpDtd0vy9oYEwLIk/+Tyr8e0nNGkfABqhcsoOs2cVUkowzuQgomcklj5mOTS3t055WhFbU6uxeI4U0hE7niHv/jKUQruQE355ozqE6lWbKwoL82I55mvwcice7EayU4nwdBROdT8j7HFLV/c7cTAw/4WyejcGD9LH/poh24Y+GFCJiOSA==";
		
		String encryptKey = "u5+KLbt5AyD3FuklVmbAg1mu7WWkhiVUw6A3lPL+8DbwDp18qY8tnMpd3SnCkzKeYoQP5+z4mihmVEt/hziYBOWmDRUxQU4w8Ce8THhKdP7DlscsypZTrzA0NNsEXWa7zedwIyX9Qg5f63be9TRgyNQ1rRyfYphEUwQQgrGXIK0=";
		//String encryptKey = "tLSqC8bd9u3kZUtAzknNekJW17qMbGEnWfBJ6xSubOnQggPPiKoXCCe76amsugSbugDMiscHtUeodn4ryakGC1MbCUIUsFbVnK3u/k8JjIxYgc4aHUuKhFsJQcojA7YSyGzniF5ta98KJgFnF1yxsld0ISoRLnnOM44De8305dQ=";
		
		String encryptIv = "aN7pnwNkW8iSM2Gx4R1keqUUKKC37iqTfPEMJgAXgOWi/9JkA4THhK/wLEO14a5sE4dLpm60jWgxQGlC3wslNO18JIqNxqsX82C1n++EsR3ivMXg47lh3Ka613LKtsdlZ2YYNEeNBYBZZs/Qg5rfV/JxVyWcKzB8FGeLah4uloc=";
		//String encryptIv = "ln/sw8ddehEzZgHNp64Okmfdc8jiPFFTKsZqGAddRHb8O9fQZu7wtPyBQ38T8hoTYdW1T34rgcnlvg8ZZaFNzMgcw34rgaJGB/NfQIZLK5VDdpAMIPCpKE+jG+knALFMZAqYeMHy6PmfN1rcW7dJZxwTEy9hHfBxiKtK4hOL3gQ=";
				
		String AESKey = decryptRSA(encryptKey, Config.DE_PRIVATEKEY);
		
		String AESIv = decryptRSA(encryptIv, Config.DE_PRIVATEKEY);
		
		String data = decryptAES(encryptData, AESKey, AESIv);
		System.out.println(data);
		
		//{playerID:"17405375",token:"c41c4d4367d11c7c79584bc01ddc0e8a",P:"0bf6aa1b5f433b57345e4622914377eb4b",platformId:"1001",sign:"GtCCCYZ1A8EVtAecLdSOfx++W122SEJ/2MVwIXAdATS1QMSvTLtbMpI/IOwnf0K5R7WefynYOncz2qSvbbHgn0fhNZEgpTrKQG02sSLUJ/ZLRZUZJnVosZ8tC9Nhs2F9E+K7crwpd8fXN8/WaURfY3d/fHr5J/A/c7X8eisHVJQ="}
		//{playerID:"17405375",token:"c41c4d4367d11c7c79584bc01ddc0e8a",P:"0bf6aa1b5f433b57345e4622914377eb4b",platformId:"1001",sign:"GtCCCYZ1A8EVtAecLdSOfx++W122SEJ/2MVwIXAdATS1QMSvTLtbMpI/IOwnf0K5R7WefynYOncz2qSvbbHgn0fhNZEgpTrKQG02sSLUJ/ZLRZUZJnVosZ8tC9Nhs2F9E+K7crwpd8fXN8/WaURfY3d/fHr5J/A/c7X8eisHVJQ="}
	}
	/** 此方法描述的是：   非空判断 **/
	public static boolean isNotNullAndTrim(String s){
		if(s != null && !s.trim().equals("") && !s.trim().equals("null"))
			return true;
		else
			return false;
	}
}
